<template>
  <div class="pro-form">
    <a-form
      v-bind="formProps"
      :model="formData"
      :layout="layout"
      :label-col="labelCol"
      :wrapper-col="wrapperCol"
      @finish="handleFinish"
      @finish-failed="handleFinishFailed"
    >
      <!-- 动态渲染表单项 -->
      <template v-for="field in visibleFields" :key="field.name">
        <a-form-item
          :name="field.name"
          :label="field.label"
          :rules="field.rules"
          :tooltip="field.tooltip"
          :extra="field.extra"
          v-show="!field.hidden"
        >
          <!-- 根据字段类型渲染不同组件 -->
          <component
            :is="getFieldComponent(field)"
            v-model:value="formData[field.name]"
            v-bind="getFieldProps(field)"
            :placeholder="field.placeholder || `请输入${field.label}`"
            :disabled="field.disabled || readonly"
          >
            <!-- 处理选择类组件的选项 -->
            <template v-if="field.valueType === 'select' && field.options">
              <a-select-option
                v-for="option in field.options"
                :key="option.value"
                :value="option.value"
                :disabled="option.disabled"
              >
                {{ option.label }}
              </a-select-option>
            </template>
            
            <template v-if="field.valueType === 'radio' && field.options">
              <a-radio
                v-for="option in field.options"
                :key="option.value"
                :value="option.value"
                :disabled="option.disabled"
              >
                {{ option.label }}
              </a-radio>
            </template>
            
            <template v-if="field.valueType === 'checkbox' && field.options">
              <a-checkbox
                v-for="option in field.options"
                :key="option.value"
                :value="option.value"
                :disabled="option.disabled"
              >
                {{ option.label }}
              </a-checkbox>
            </template>
          </component>
        </a-form-item>
      </template>

      <!-- 操作按钮 -->
      <a-form-item v-if="showSubmit" :wrapper-col="submitWrapperCol">
        <a-space>
          <a-button
            type="primary"
            html-type="submit"
            :loading="submitting"
            :disabled="readonly"
          >
            {{ submitText }}
          </a-button>
          <a-button v-if="showReset" @click="handleReset" :disabled="readonly">
            {{ resetText }}
          </a-button>
          <slot name="actions" />
        </a-space>
      </a-form-item>

      <!-- 自定义插槽 -->
      <template v-for="(_, name) in $slots" #[name]="slotData">
        <slot :name="name" v-bind="slotData" />
      </template>
    </a-form>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, reactive } from 'vue'
import type { FormProps, Rule } from 'ant-design-vue/es/form'
import type { ColProps } from 'ant-design-vue/es/grid'

interface FieldOption {
  label: string
  value: any
  disabled?: boolean
}

interface ProFormField {
  name: string
  label: string
  valueType?: 'text' | 'password' | 'number' | 'textarea' | 'select' | 'radio' | 'checkbox' | 'date' | 'dateRange' | 'time' | 'switch' | 'rate' | 'slider' | 'upload'
  placeholder?: string
  tooltip?: string
  extra?: string
  rules?: Rule[]
  disabled?: boolean
  hidden?: boolean
  options?: FieldOption[]
  fieldProps?: Record<string, any>
  dependencies?: string[]
}

interface ProFormProps extends Omit<FormProps, 'model'> {
  fields: ProFormField[]
  initialValues?: Record<string, any>
  readonly?: boolean
  showSubmit?: boolean
  showReset?: boolean
  submitText?: string
  resetText?: string
  submitting?: boolean
  onSubmit?: (values: Record<string, any>) => void | Promise<void>
  onReset?: () => void
}

const props = withDefaults(defineProps<ProFormProps>(), {
  layout: 'horizontal',
  showSubmit: true,
  showReset: true,
  submitText: '提交',
  resetText: '重置',
  readonly: false,
  submitting: false,
})

const emit = defineEmits<{
  submit: [values: Record<string, any>]
  reset: []
  valuesChange: [changedValues: Record<string, any>, allValues: Record<string, any>]
}>()

// 响应式数据
const formData = reactive<Record<string, any>>({})

// 初始化表单数据
watch(() => props.initialValues, (newValues) => {
  if (newValues) {
    Object.assign(formData, newValues)
  }
}, { immediate: true, deep: true })

watch(() => props.fields, (newFields) => {
  // 初始化字段默认值
  newFields.forEach(field => {
    if (!(field.name in formData)) {
      formData[field.name] = getDefaultValue(field.valueType)
    }
  })
}, { immediate: true })

// 计算属性
const formProps = computed(() => {
  const { fields, initialValues, readonly, showSubmit, showReset, submitText, resetText, submitting, onSubmit, onReset, ...rest } = props
  return rest
})

const visibleFields = computed(() => {
  return props.fields.filter(field => {
    // 处理依赖字段的显示逻辑
    if (field.dependencies) {
      return field.dependencies.every(dep => {
        const depValue = formData[dep]
        return depValue !== undefined && depValue !== null && depValue !== ''
      })
    }
    return true
  })
})

const labelCol = computed((): ColProps => {
  if (props.layout === 'vertical') return {}
  return props.labelCol || { span: 6 }
})

const wrapperCol = computed((): ColProps => {
  if (props.layout === 'vertical') return {}
  return props.wrapperCol || { span: 18 }
})

const submitWrapperCol = computed((): ColProps => {
  if (props.layout === 'vertical') return {}
  return { offset: labelCol.value.span || 6, span: wrapperCol.value.span || 18 }
})

// 方法
const getDefaultValue = (valueType?: string) => {
  switch (valueType) {
    case 'number':
      return undefined
    case 'switch':
      return false
    case 'checkbox':
      return []
    case 'rate':
      return 0
    case 'slider':
      return 0
    default:
      return undefined
  }
}

const getFieldComponent = (field: ProFormField) => {
  switch (field.valueType) {
    case 'password':
      return 'a-input-password'
    case 'number':
      return 'a-input-number'
    case 'textarea':
      return 'a-textarea'
    case 'select':
      return 'a-select'
    case 'radio':
      return 'a-radio-group'
    case 'checkbox':
      return 'a-checkbox-group'
    case 'date':
      return 'a-date-picker'
    case 'dateRange':
      return 'a-range-picker'
    case 'time':
      return 'a-time-picker'
    case 'switch':
      return 'a-switch'
    case 'rate':
      return 'a-rate'
    case 'slider':
      return 'a-slider'
    case 'upload':
      return 'a-upload'
    default:
      return 'a-input'
  }
}

const getFieldProps = (field: ProFormField) => {
  const baseProps = field.fieldProps || {}
  
  switch (field.valueType) {
    case 'textarea':
      return { rows: 4, ...baseProps }
    case 'number':
      return { style: { width: '100%' }, ...baseProps }
    case 'select':
      return { allowClear: true, ...baseProps }
    case 'date':
    case 'time':
      return { style: { width: '100%' }, ...baseProps }
    case 'dateRange':
      return { style: { width: '100%' }, ...baseProps }
    case 'upload':
      return { 
        listType: 'text',
        beforeUpload: () => false,
        ...baseProps 
      }
    default:
      return baseProps
  }
}

const handleFinish = async (values: Record<string, any>) => {
  emit('submit', values)
  if (props.onSubmit) {
    await props.onSubmit(values)
  }
}

const handleFinishFailed = (errorInfo: any) => {
  console.error('表单验证失败:', errorInfo)
}

const handleReset = () => {
  // 重置为初始值
  Object.keys(formData).forEach(key => {
    if (props.initialValues && key in props.initialValues) {
      formData[key] = props.initialValues[key]
    } else {
      const field = props.fields.find(f => f.name === key)
      formData[key] = getDefaultValue(field?.valueType)
    }
  })
  
  emit('reset')
  if (props.onReset) {
    props.onReset()
  }
}

// 监听表单值变化
watch(formData, (newValues, oldValues) => {
  const changedValues: Record<string, any> = {}
  Object.keys(newValues).forEach(key => {
    if (newValues[key] !== oldValues?.[key]) {
      changedValues[key] = newValues[key]
    }
  })
  
  if (Object.keys(changedValues).length > 0) {
    emit('valuesChange', changedValues, { ...newValues })
  }
}, { deep: true })

// 暴露方法
defineExpose({
  getFieldsValue: () => ({ ...formData }),
  setFieldsValue: (values: Record<string, any>) => {
    Object.assign(formData, values)
  },
  resetFields: handleReset,
  validateFields: () => {
    // 这里可以添加表单验证逻辑
    return Promise.resolve(formData)
  }
})
</script>

<style scoped>
.pro-form {
  background: #fff;
  border-radius: 8px;
  padding: 24px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .pro-form {
    padding: 16px;
  }
}
</style>